import sympy as sp
import matplotlib.pyplot as plt

# 中文显示
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei']
# 支持负数
plt.rcParams['axes.unicode_minus'] = False

def derivative_applications():
    x = sp.Symbol('x')
    
    print("=== 导数几何应用：切线与极值 ===")
    
    # 示例函数
    f = x**3 - 3*x**2 + 2*x + 1
    print(f"示例函数: f(x) = {f}\n")
    
    # 1. 求切线方程（在x=1处）
    print("1. 切线方程求解")
    x0 = 1
    f_x0 = f.subs(x, x0)
    f_prime = sp.diff(f, x)
    f_prime_x0 = f_prime.subs(x, x0)
    
    # 切线方程: y - f(x0) = f'(x0)(x - x0)
    tangent_line = f_prime_x0 * (x - x0) + f_x0
    
    print(f"在 x = {x0} 处:")
    print(f"  函数值: f({x0}) = {f_x0}")
    print(f"  导数值（斜率）: f'({x0}) = {f_prime_x0}")
    print(f"  切线方程: y = {tangent_line}")
    
    # 可视化切线
    try:
        import numpy as np
        import matplotlib.pyplot as plt
        
        x_vals = np.linspace(0, 2, 100)
        f_vals = [f.subs(x, val) for val in x_vals]
        tangent_vals = [tangent_line.subs(x, val) for val in x_vals]
        
        plt.figure(figsize=(10, 6))
        plt.plot(x_vals, f_vals, label=f'f(x) = {f}')
        plt.plot(x_vals, tangent_vals, label=f'切线在x={x0}处', linestyle='--')
        plt.scatter([x0], [f_x0], color='red', zorder=5)
        plt.xlabel('x')
        plt.ylabel('y')
        plt.title('函数图像与切线')
        plt.legend()
        plt.grid(True)
        plt.show()
    except:
        print("（可视化需要matplotlib库）\n")
    
    # 2. 寻找临界点（导数为零的点）和极值
    print("\n2. 极值点分析")
    critical_points = sp.solve(f_prime, x)
    print(f"临界点（导数为零的点）: {critical_points}")
    
    # 二阶导数测试
    f_double_prime = sp.diff(f_prime, x)
    print(f"二阶导数: f''(x) = {f_double_prime}")
    
    for point in critical_points:
        # 确保点是实数
        if point.is_real:
            point_value = f.subs(x, point)
            second_deriv_value = f_double_prime.subs(x, point)
            
            if second_deriv_value > 0:
                extremum_type = "局部极小值"
            elif second_deriv_value < 0:
                extremum_type = "局部极大值"
            else:
                extremum_type = "可能是拐点（需进一步检验）"
            
            print(f"点 x = {point:.2f}:")
            print(f"  函数值: f({point:.2f}) = {point_value:.2f}")
            print(f"  二阶导数: f''({point:.2f}) = {second_deriv_value:.2f}")
            print(f"  极值类型: {extremum_type}")

# 运行应用示例
derivative_applications()